package com.tyrone.concurrent.basic;

import com.tyrone.concurrent.utils.SleepUtils;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.SimpleTimeZone;
import java.util.concurrent.TimeUnit;

/**
 * 等待/通知 经典范式
 * 等待方：
 * synchronized(对象){
 *     while(条件不足){
 *         对象.wait;
 *     }
 *     逻辑处理;
 * }
 * 通知方：
 * synchronized(对象){
 *     逻辑处理;
 *     对象.notify； //  对象.notifyAll();
 *
 * }
 * @author xieyl
 * @create 2021/12/3 17:33
 */
public class WaitNotify {
    static boolean flag = true;
    static Object lock = new Object();

    public static void main(String[] args) throws Exception {
        Thread waitThread = new Thread(new Wait(), "WaitThread");
        waitThread.start();
        TimeUnit.SECONDS.sleep(1);
        Thread notifyThread = new Thread(new Notify(), "NotifyThread");
        notifyThread.start();
    }

    static class Wait implements Runnable {
        @Override
        public void run() {
            synchronized (lock) {
                while (flag) {
                    try {
                        System.out.println(Thread.currentThread() + "  flag is ture. wait@)" +
                                new SimpleDateFormat("HH:mm:ss").format(new Date()));
                        lock.wait();
                    } catch (InterruptedException e) {

                    }
                }
                System.out.println(Thread.currentThread() + "  flag is false. running@)" +
                        new SimpleDateFormat("HH:mm:ss").format(new Date()));
            }
        }
    }

    static class Notify implements Runnable {
        @Override
        public void run() {
            synchronized (lock) {
                System.out.println(Thread.currentThread() + "  hold lock. notify@)" +
                        new SimpleDateFormat("HH:mm:ss").format(new Date()));
                lock.notify();
                flag = false;
                SleepUtils.second(5);

            }
            synchronized (lock) {
                System.out.println(Thread.currentThread() + "  hold lock again. notify@)" +
                        new SimpleDateFormat("HH:mm:ss").format(new Date()));
                SleepUtils.second(5);
            }
        }
    }

}
